/**
 * 
 */
package cmsc495.mach2.test;

import cmsc495.mach2.CalculationHandler;
import cmsc495.mach2.unit.MetricUnit;
import cmsc495.mach2.unit.english.EnglishAreaUnit;
import cmsc495.mach2.unit.english.EnglishDryCapacityUnit;
import cmsc495.mach2.unit.english.EnglishLengthUnit;
import cmsc495.mach2.unit.english.EnglishMassUnit;
import cmsc495.mach2.unit.english.EnglishVolumeUnit;
import cmsc495.mach2.unit.english.EnglishWetCapacityUnit;
import junit.framework.TestCase;

/**
 * @author Michael Swann
 * 
 */
public class CalculationHandlerValidation extends TestCase {

	private static final int			LENGTH						= 0;
	private static final int			AREA						= 1;
	private static final int			VOLUME						= 2;
	private static final int			DRYCAPACITY					= 3;
	private static final int			WETCAPACITY					= 4;
	private static final int			MASS						= 5;
	private static final int			TEMPERATURE					= 6;

	private static final double			VALUE						= 1.0;

	//Length Positions
	private final static int			ENGLISH_LENGTH_START		= 0;
	private final static int			ENGLISH_LENGTH_END			= 3;
	private final static int			METRIC_LENGTH_START			= 4;
	private final static int			METRIC_LENGTH_END			= 10;
	//Area Positions
	private final static int			ENGLISH_AREA_START			= 0;
	private final static int			ENGLISH_AREA_END			= 4;
	private final static int			METRIC_AREA_START			= 5;
	private final static int			METRIC_AREA_END				= 11;
	//Volume Positions
	private final static int			ENGLISH_VOLUME_START		= 0;
	private final static int			ENGLISH_VOLUME_END			= 2;
	private final static int			METRIC_VOLUME_START			= 3;
	private final static int			METRIC_VOLUME_END			= 9;
	//Dry Capacity Positions
	private final static int			ENGLISH_DRY_CAPACITY_START	= 0;
	private final static int			ENGLISH_DRY_CAPACITY_END	= 3;
	private final static int			METRIC_DRY_CAPACITY_START	= 4;
	private final static int			METRIC_DRY_CAPACITY_END		= 10;
	//Wet Capacity Positions
	private final static int			ENGLISH_WET_CAPACITY_START	= 0;
	private final static int			ENGLISH_WET_CAPACITY_END	= 3;
	private final static int			METRIC_WET_CAPACITY_START	= 4;
	private final static int			METRIC_WET_CAPACITY_END		= 10;
	//Mass Positions
	private final static int			ENGLISH_MASS_START			= 0;
	private final static int			ENGLISH_MASS_END			= 4;
	private final static int			METRIC_MASS_START			= 5;
	private final static int			METRIC_MASS_END				= 11;

	private EnglishLengthUnit[]			englishLengthUnits;
	private EnglishAreaUnit[]			englishAreaUnits;
	private EnglishVolumeUnit[]			englishVolumeUnits;
	private EnglishDryCapacityUnit[]	englishDryCapacityUnits;
	private EnglishWetCapacityUnit[]	englishWetCapacityUnits;
	private EnglishMassUnit[]			englishMassUnits;
	private MetricUnit[]				metricUnits;

	private static final double			DELTA						= 0.01;

	public CalculationHandlerValidation() {
	}

	@Override
	protected void setUp() throws Exception {
		super.setUp();

		englishLengthUnits = EnglishLengthUnit.values();
		englishAreaUnits = EnglishAreaUnit.values();
		englishVolumeUnits = EnglishVolumeUnit.values();
		englishDryCapacityUnits = EnglishDryCapacityUnit.values();
		englishWetCapacityUnits = EnglishWetCapacityUnit.values();
		englishMassUnits = EnglishMassUnit.values();
		metricUnits = MetricUnit.values();
	}

	public final void testEnglishToEnglish() {
		double aResult = 0.0;
		double result = 0.0;

		aResult = englishLengthUnits[ENGLISH_LENGTH_END].convert(VALUE, englishLengthUnits[ENGLISH_LENGTH_START]);
		result = CalculationHandler.parseAndCalculate(LENGTH, ENGLISH_LENGTH_START, ENGLISH_LENGTH_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishLengthUnits[ENGLISH_LENGTH_START] + " TO " + englishLengthUnits[ENGLISH_LENGTH_END]);
		assertEquals(aResult, result, DELTA);

		aResult = englishAreaUnits[ENGLISH_AREA_END].convert(VALUE, englishAreaUnits[ENGLISH_AREA_START]);
		result = CalculationHandler.parseAndCalculate(AREA, ENGLISH_AREA_START, ENGLISH_AREA_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishAreaUnits[ENGLISH_AREA_START] + " TO " + englishAreaUnits[ENGLISH_AREA_END]);
		assertEquals(aResult, result, DELTA);

		aResult = englishVolumeUnits[ENGLISH_VOLUME_END].convert(VALUE, englishVolumeUnits[ENGLISH_VOLUME_START]);
		result = CalculationHandler.parseAndCalculate(VOLUME, ENGLISH_VOLUME_START, ENGLISH_VOLUME_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishVolumeUnits[ENGLISH_VOLUME_START] + " TO " + englishVolumeUnits[ENGLISH_VOLUME_END]);
		assertEquals(aResult, result, DELTA);

		aResult = englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_END].convert(VALUE, englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_START]);
		result = CalculationHandler.parseAndCalculate(DRYCAPACITY, ENGLISH_DRY_CAPACITY_START, ENGLISH_DRY_CAPACITY_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_START] + " TO "
				+ englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_END]);
		assertEquals(aResult, result, DELTA);

		aResult = englishWetCapacityUnits[ENGLISH_WET_CAPACITY_END].convert(VALUE, englishWetCapacityUnits[ENGLISH_WET_CAPACITY_START]);
		result = CalculationHandler.parseAndCalculate(WETCAPACITY, ENGLISH_WET_CAPACITY_START, ENGLISH_WET_CAPACITY_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishWetCapacityUnits[ENGLISH_WET_CAPACITY_START] + " TO "
				+ englishWetCapacityUnits[ENGLISH_WET_CAPACITY_END]);
		assertEquals(aResult, result, DELTA);

		aResult = englishMassUnits[ENGLISH_MASS_END].convert(VALUE, englishMassUnits[ENGLISH_MASS_START]);
		result = CalculationHandler.parseAndCalculate(MASS, ENGLISH_MASS_START, ENGLISH_MASS_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishMassUnits[ENGLISH_MASS_START] + " TO " + englishMassUnits[ENGLISH_MASS_END]);
		assertEquals(aResult, result, DELTA);
	}

	/**
	 * Test Method for Metric to English Checks CalculationHandler for correct
	 * parsing on: First Metric Unit to First English Unit
	 */
	public final void testMetricToEnglish() {
		double aResult = 0.0;
		double result = 0.0;
		double tempConv = 0.0;

		tempConv = metricUnits[0].toEnglishInches(VALUE);
		aResult = englishLengthUnits[ENGLISH_LENGTH_START].convert(tempConv, EnglishLengthUnit.INCHES);
		result = CalculationHandler.parseAndCalculate(LENGTH, METRIC_LENGTH_START, ENGLISH_LENGTH_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + englishLengthUnits[ENGLISH_LENGTH_START]);
		assertEquals(aResult, result, DELTA);

		tempConv = metricUnits[0].toEnglishSquareInches(VALUE);
		aResult = englishAreaUnits[ENGLISH_AREA_START].convert(tempConv, EnglishAreaUnit.SQUAREINCHES);
		result = CalculationHandler.parseAndCalculate(AREA, METRIC_AREA_START, ENGLISH_AREA_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + englishAreaUnits[ENGLISH_AREA_START]);
		assertEquals(aResult, result, DELTA);

		tempConv = metricUnits[0].toEnglishCubicInches(VALUE);
		aResult = englishVolumeUnits[ENGLISH_VOLUME_START].convert(tempConv, EnglishVolumeUnit.CUBICINCHES);
		result = CalculationHandler.parseAndCalculate(VOLUME, METRIC_VOLUME_START, ENGLISH_VOLUME_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + englishVolumeUnits[ENGLISH_VOLUME_START]);
		assertEquals(aResult, result, DELTA);

		tempConv = metricUnits[0].toEnglishDryQuarts(VALUE);
		aResult = englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_START].convert(tempConv, EnglishDryCapacityUnit.QUARTS);
		result = CalculationHandler.parseAndCalculate(DRYCAPACITY, METRIC_DRY_CAPACITY_START, ENGLISH_DRY_CAPACITY_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_START]);
		assertEquals(aResult, result, DELTA);

		tempConv = metricUnits[0].toEnglishWetQuarts(VALUE);
		aResult = englishWetCapacityUnits[ENGLISH_WET_CAPACITY_START].convert(tempConv, EnglishWetCapacityUnit.QUARTS);
		result = CalculationHandler.parseAndCalculate(WETCAPACITY, METRIC_WET_CAPACITY_START, ENGLISH_WET_CAPACITY_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + englishWetCapacityUnits[ENGLISH_WET_CAPACITY_START]);
		assertEquals(aResult, result, DELTA);

		tempConv = metricUnits[0].toEnglishOunces(VALUE);
		aResult = englishMassUnits[ENGLISH_MASS_START].convert(tempConv, EnglishMassUnit.OUNCES);
		result = CalculationHandler.parseAndCalculate(MASS, METRIC_MASS_START, ENGLISH_MASS_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + englishMassUnits[ENGLISH_MASS_START]);
		assertEquals(aResult, result, DELTA);
	}

	/**
	 * Test Method for English to Metric Checks CalculationHandler for correct
	 * parsing on: First English Unit to First Metric Unit
	 */
	public final void testEnglishToMetric() {
		double aResult = 0.0;
		double result = 0.0;
		double tempConv = 0.0;

		tempConv = englishLengthUnits[ENGLISH_LENGTH_START].toMeters(VALUE);
		aResult = metricUnits[0].convert(tempConv, MetricUnit.BASE);
		result = CalculationHandler.parseAndCalculate(LENGTH, ENGLISH_LENGTH_START, METRIC_LENGTH_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishLengthUnits[ENGLISH_LENGTH_START] + " TO " + metricUnits[0]);
		assertEquals(aResult, result, DELTA);

		tempConv = englishAreaUnits[ENGLISH_AREA_START].toSquareMeters(VALUE);
		aResult = metricUnits[0].convert(tempConv, MetricUnit.BASE);
		result = CalculationHandler.parseAndCalculate(AREA, ENGLISH_AREA_START, METRIC_AREA_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishAreaUnits[ENGLISH_AREA_START] + " TO " + metricUnits[0]);
		assertEquals(aResult, result, DELTA);

		tempConv = englishVolumeUnits[ENGLISH_VOLUME_START].toCubicMeters(VALUE);
		aResult = metricUnits[0].convert(tempConv, MetricUnit.BASE);
		result = CalculationHandler.parseAndCalculate(VOLUME, ENGLISH_VOLUME_START, METRIC_VOLUME_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishVolumeUnits[ENGLISH_VOLUME_START] + " TO " + metricUnits[0]);
		assertEquals(aResult, result, DELTA);

		tempConv = englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_START].toLiters(VALUE);
		aResult = metricUnits[0].convert(tempConv, MetricUnit.BASE);
		result = CalculationHandler.parseAndCalculate(DRYCAPACITY, ENGLISH_DRY_CAPACITY_START, METRIC_DRY_CAPACITY_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishDryCapacityUnits[ENGLISH_DRY_CAPACITY_START] + " TO " + metricUnits[0]);
		assertEquals(aResult, result, DELTA);

		tempConv = englishWetCapacityUnits[ENGLISH_WET_CAPACITY_START].toLiters(VALUE);
		aResult = metricUnits[0].convert(tempConv, MetricUnit.BASE);
		result = CalculationHandler.parseAndCalculate(WETCAPACITY, ENGLISH_WET_CAPACITY_START, METRIC_WET_CAPACITY_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishWetCapacityUnits[ENGLISH_WET_CAPACITY_START] + " TO " + metricUnits[0]);
		assertEquals(aResult, result, DELTA);

		tempConv = englishMassUnits[ENGLISH_MASS_START].toGrams(VALUE);
		aResult = metricUnits[0].convert(tempConv, MetricUnit.BASE);
		result = CalculationHandler.parseAndCalculate(MASS, ENGLISH_MASS_START, METRIC_MASS_START, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + englishMassUnits[ENGLISH_MASS_START] + " TO " + metricUnits[0]);
		assertEquals(aResult, result, DELTA);
	}

	/**
	 * Test Method for Metric to Metric Checks CalculationHandler for correct
	 * parsing on: First Metric Unit to last Metric Unit
	 */
	public final void testMetricToMetric() {
		double aResult = 0.0;
		double result = 0.0;
		int metricUnitslength = metricUnits.length - 1;

		aResult = metricUnits[metricUnitslength].convert(VALUE, metricUnits[0]);
		result = CalculationHandler.parseAndCalculate(LENGTH, METRIC_LENGTH_START, METRIC_LENGTH_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + metricUnits[metricUnitslength]);
		assertEquals(aResult, result);

		aResult = metricUnits[metricUnitslength].convert(VALUE, metricUnits[0]);
		result = CalculationHandler.parseAndCalculate(AREA, METRIC_AREA_START, METRIC_AREA_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + metricUnits[metricUnitslength]);
		assertEquals(aResult, result);

		aResult = metricUnits[metricUnitslength].convert(VALUE, metricUnits[0]);
		result = CalculationHandler.parseAndCalculate(VOLUME, METRIC_VOLUME_START, METRIC_VOLUME_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + metricUnits[metricUnitslength]);
		assertEquals(aResult, result);

		aResult = metricUnits[metricUnitslength].convert(VALUE, metricUnits[0]);
		result = CalculationHandler.parseAndCalculate(DRYCAPACITY, METRIC_DRY_CAPACITY_START, METRIC_DRY_CAPACITY_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + metricUnits[metricUnitslength]);
		assertEquals(aResult, result);

		aResult = metricUnits[metricUnitslength].convert(VALUE, metricUnits[0]);
		result = CalculationHandler.parseAndCalculate(WETCAPACITY, METRIC_WET_CAPACITY_START, METRIC_WET_CAPACITY_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + metricUnits[metricUnitslength]);
		assertEquals(aResult, result);

		aResult = metricUnits[metricUnitslength].convert(VALUE, metricUnits[0]);
		result = CalculationHandler.parseAndCalculate(MASS, METRIC_MASS_START, METRIC_MASS_END, VALUE);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " " + metricUnits[0] + " TO " + metricUnits[metricUnitslength]);
		assertEquals(aResult, result);
	}

	/**
	 * Test Method for Metric to Metric Checks CalculationHandler for correct
	 * parsing on: First Temperature Unit to Last Temperature Unit (Celsius to Rankine)
	 */
	public final void testTemperature() {
		double aResult = 1031.67;
		double result = 0;

		result = CalculationHandler.parseAndCalculate(TEMPERATURE, 0, 3, 300);
		System.out.println("ASSERT: " + aResult + " = " + result + " : " + VALUE + " CELSIUS TO RANKINE");
		assertEquals(aResult, result);
	}
}
